﻿// <copyright file="HoverKinectZone.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace KinectExtensions.Nui
{
    #region

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Threading;

    using KinectExtensions.Controls;

    #endregion

    /// <summary>
    ///   TODO: Update summary.
    /// </summary>
    public class HoverKinectZone : IKinectZone, INotifyPropertyChanged
    {
        #region Constants and Fields

        /// <summary>
        ///   The timer.
        /// </summary>
        private readonly DispatcherTimer timer;

        /// <summary>
        ///   The is waiting.
        /// </summary>
        private bool isWaiting;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        ///   Initializes a new instance of the <see cref = "HoverKinectZone" /> class.
        /// </summary>
        public HoverKinectZone()
        {
            this.timer = new DispatcherTimer();
            this.timer.Tick += this.timer_Tick;
        }

        #endregion

        #region Public Events

        /// <summary>
        ///   The property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets or sets Action.
        /// </summary>
        public Action Action { get; set; }

        /// <summary>
        ///   Gets or sets HoverActionDelayDuration.
        /// </summary>
        public TimeSpan HoverActionDelayDuration { get; set; }

        /// <summary>
        ///   Gets or sets a value indicating whether IsWaiting.
        /// </summary>
        public bool IsWaiting
        {
            get
            {
                return this.isWaiting;
            }

            set
            {
                if (this.isWaiting != value)
                {
                    this.isWaiting = value;
                    this.RaisePropertyChanged(n => n.IsWaiting);
                }
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        ///   The enter.
        /// </summary>
        public virtual void Enter()
        {
            this.timer.Interval = this.HoverActionDelayDuration;
            this.timer.Start();
            this.IsWaiting = true;
        }

        /// <summary>
        ///   The handle cursor move.
        /// </summary>
        /// <param name = "cursor">
        ///   The cursor.
        /// </param>
        /// <param name = "transform">
        ///   The transform.
        /// </param>
        /// <returns>
        ///   The handle cursor move.
        /// </returns>
        public virtual bool HandleCursorMove(KinectCursor cursor, TranslateTransform transform, Point target)
        {
            return false;
        }

        /// <summary>
        ///   The leave.
        /// </summary>
        public virtual void Leave()
        {
            this.timer.Stop();
        }

        #endregion

        #region Methods

        /// <summary>
        ///   The raise property changed.
        /// </summary>
        /// <param name = "expression">
        ///   The expression.
        /// </param>
        /// <typeparam name = "TProperty">
        /// </typeparam>
        protected void RaisePropertyChanged<TProperty>(Expression<Func<HoverKinectZone, TProperty>> expression)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(this.GetPropertyName(expression)));
            }
        }

        /// <summary>
        ///   The timer_ tick.
        /// </summary>
        /// <param name = "sender">
        ///   The sender.
        /// </param>
        /// <param name = "e">
        ///   The e.
        /// </param>
        private void timer_Tick(object sender, EventArgs e)
        {
            this.timer.Stop();
            if (this.Action != null)
            {
                this.Action();
            }

            this.IsWaiting = false;
        }

        #endregion
    }
}